/*
 * mouse.c
 *
 *  Created on: 2016年7月27日
 *      Author: pengzhikang
 */

#include "naskfunc.h"
#include "keyboard.h"
#include "int.h"

struct FIFO32 *mousefifo;
int mousedata0;

/* 处理来自PS/2鼠标的中断 由naskfunc.nas中的_asm_inthandler2c调用 */
void inthandler2c(int *esp) {
	int data;
	io_out8(PIC1_OCW2, 0x64);
	io_out8(PIC0_OCW2, 0x62);
	data = io_in8(PORT_KEYDAT);
	fifo32_put(mousefifo, data + mousedata0);
}

void enable_mouse(struct FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec) {
	mousefifo =fifo;
	mousedata0 = data0;

	wait_KBC_sendready(); /* 清空i8042的输入缓冲区 */
	/* 向i8042写入命令,该命令表示将发生0x60端口的参数数据发生给鼠标	*/
	io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
	wait_KBC_sendready();
	io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
	// 等待0xfa的阶段
	mdec->phase = 0;
	return;

}

/**
 * 接收鼠标数据
 * 关于鼠标发送的3个字节的各bit具体含义,请参考群共享中的"PS2鼠标键盘协议-仅含PS2部分.pdf"
 */
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) {
	// 鼠标共有三个字节，接收到鼠标要发送数据的状态0xfa后，读三个字节
	if (mdec->phase == 0) {
		if (dat == 0xfa) {
			mdec->phase = 1;
		}
		return 0;
	}
	if (mdec->phase == 1) {
		if ((dat & 0xc8) == 0x08) {
			mdec->buf[0] = dat;
			mdec->phase = 2;
		}
		return 0;
	}
	if (mdec->phase == 2) {
		mdec->buf[1] = dat;
		mdec->phase = 3;
		return 0;
	}
	if (mdec->phase == 3) {
		mdec->buf[2] = dat;
		mdec->phase = 1;
		// 0x07=0000 0111,取低三位
		mdec->btn = mdec->buf[0] & 0x07;
		mdec->x = mdec->buf[1];

		mdec->y = mdec->buf[2];
		// 0x10=0001 0000,
		if ((mdec->buf[0] & 0x10) != 0) {
			mdec->x |= 0xffffff00;
		}
		// 0x10=0010 0000,
		if ((mdec->buf[0] & 0x20) != 0) {
			mdec->y |= 0xffffff00;
		}
		mdec->y = -mdec->y;
		return 1;
	}
	return -1;
}
